package cs6238.server;

import java.security.Key;
import java.security.KeyStore;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import cs6238.common.CertificateHelper;
import cs6238.common.Configuration;

public class FileEncryptor {
	
	private static final byte[] IV = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
	
	/**
	 * Just create a hash of the byte array
	 * @param input
	 * @return
	 * @throws Exception
	 */
	public static byte[] createHash(byte[] input) throws Exception{
		MessageDigest md = MessageDigest.getInstance("MD5");
		return md.digest(input);
	}
	
	/**
	 * encrypt hash using server's public key
	 * @param hash
	 * @return
	 */
	public static byte[] encryptHash(byte[] hash){
		Configuration serverConfig = Configuration.loadServerSettings();
		String keystorePath = serverConfig.getSetting(Configuration.KEYSTORE_PATH);
		String keystorePassword = serverConfig.getSetting(Configuration.KEYSTORE_PASSWORD);
		try{
			KeyStore store = CertificateHelper.readJKS(keystorePath, keystorePassword);
			return CertificateHelper.encryptMessage(store, hash);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * decrypt hash using server's private key
	 * @param hash
	 * @return
	 */
	public static byte[] decryptHash(byte[] hash){
		Configuration serverConfig = Configuration.loadServerSettings();
		String keystorePath = serverConfig.getSetting(Configuration.KEYSTORE_PATH);
		String keystorePassword = serverConfig.getSetting(Configuration.KEYSTORE_PASSWORD);
		try{
			KeyStore store = CertificateHelper.readJKS(keystorePath, keystorePassword);
			return CertificateHelper.decryptMessage(store, keystorePassword, hash);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * Encrypt byte array using hash as a key
	 * @param input
	 * @param hash
	 * @return
	 * @throws Exception
	 */
	public static byte[] encrypt(byte[] input, byte[] hash) throws Exception{
		Key key = new SecretKeySpec(hash, "AES");
		Cipher in = Cipher.getInstance("AES/EAX/NoPadding", "BC");
		in.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV));
		return in.doFinal(input);
	}
	
	
	public static byte[] decrypt(byte[] input, byte[] hash) throws Exception{
		Key key = new SecretKeySpec(hash, "AES");
		Cipher out = Cipher.getInstance("AES/EAX/NoPadding", "BC");
		out.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(IV));
		byte[] dec = out.doFinal(input);
		return dec;
	}
}
